package org.fhm.zdte.server.service;

import org.fhm.substrate.annotation.Component;
import org.fhm.substrate.annotation.Setup;
import org.fhm.substrate.standard.IStarter;
import org.fhm.zdte.common.annotation.Provider;
import org.fhm.zdte.common.exception.ServletException;
import org.fhm.zdte.common.pojo.Request;
import org.fhm.zdte.common.pojo.Result;
import org.fhm.zdte.common.standard.IInterfaceScheduler;
import org.fhm.zdte.common.standard.IJsonConvertor;

import java.lang.annotation.Annotation;
import java.util.Collections;
import java.util.List;

/**
 * The client side implementation of JSubstrate's {@link IStarter}.
 *
 * @author 谭波
 * @since 2023/11/22
 */
@Component
public final class ServerStarter extends AbstractServerStarter {

    @Setup("OUTWARD")
    private IInterfaceScheduler iInterfaceScheduler;

    @Setup
    private IJsonConvertor iJsonConvertor;

    @Override
    public List<Class<? extends Annotation>> newManageMembers() {
        return Collections.singletonList(Provider.class);
    }

    @Override
    public void manageNotify(List<?> beans, Class<? extends Annotation> clazz) {
        try {
            iInterfaceScheduler.mappingInterfaceWithMethods(beans);
        } catch (ServletException e) {
            try {
                close();
            } catch (Exception ignore) {
            }
            throw new RuntimeException(e);
        }
    }

    @Override
    public Result<String> dispatchServlet(String from, Request bean) {
        Result<String> result;
        try {
            result = Result.reSetResult(
                    iInterfaceScheduler
                            .invokedMethodByInterfaceUrl(
                                    from,
                                    bean.getInterfaceUrl(),
                                    bean.getParams()
                            ),
                    content -> iJsonConvertor.toJson(content)
            );
        } catch (Exception e) {
            result = Result.getFailResult("", e.getMessage());
        }
        return result;
    }

    @Override
    public Result<?> dispatchInternalServlet(Request bean) {
        return Result.getFailResult("not implemented yet");
    }

    @Override
    public void start(String[] args) {
        api.onlineCheck();
    }
}